import { CloseCircleFilled, BookOutlined } from '@ant-design/icons'
import { keywordCompare } from '@gnlab/utils'
import { useAsyncEffect, useRefValue } from '@gnlab/utils/env-react'
import { Tag, Input, Button, message, Checkbox, Tooltip } from 'antd'
import { OrderedMap } from 'immutable'
import pick from 'lodash/pick'
import ChooseGroupTags from '@/desktop/components/ChooseGroupTags'
import  defaultAvatar  from '@/desktop/assets/avatar.jpg'
import services from '@/services'
import type { GroupTag } from '@/services/contact-types'
import type {
  BaseBatchApplyConfig,
  BatchApplyGroup,
  BaseBatchApplyGroup,
  BatchApplyConfigQywx,
} from '@/services/features/group-batch-apply'
import './ChooseGroups.module.less'

interface FormattedGroup extends BatchApplyGroup {
  qywxName: string
}

export default function ChooseGroups(props: {
  wxids: string[]
  qywxs: BatchApplyConfigQywx[]
  groups: BaseBatchApplyGroup[]
  goPrev: (updates?: Partial<BaseBatchApplyConfig>) => void
  choosed: (groups: BaseBatchApplyGroup[]) => void
}) {
  const {
    wxids,
    qywxs,
    groups: initialChoosedGroups,
    goPrev: propsGoPrev,
    choosed: propsChoosed,
  } = props
  const qywxsRef = useRefValue(qywxs)

  const [groups, setGroups] = useState<FormattedGroup[]>([])
  useAsyncEffect(async () => {
    const res = await services.features.groupBatchApply.getGroupsForConfig(wxids)
    if (res.success) {
      setGroups(
        res.data.map(g => ({
          ...g,
          qywxName: qywxs.find(q => q.wxid === g.ownerWxid)?.friendlyFullName ?? '',
        })),
      )
    } else void message.warning('群列表加载失败')
  }, [qywxsRef])

  const [tags, setTags] = useState<GroupTag[]>([])
  const [choosingTags, setChoosingTags] = useState(false)
  const finishChooseTags = useCallback((result?: GroupTag[]) => {
    if (result) setTags(result)
    setChoosingTags(false)
  }, [])
  const removeTag = useCallback(
    (id: number) => {
      setTags(tags.filter(t => t.id !== id))
    },
    [tags],
  )

  const [keyword, setKeyword] = useState('')
  const [includeExternal, setIncludeExternal] = useState(true) // 显示自己公司的“外部群”
  const [includeCorpExternal, setIncludeCorpExternal] = useState(true) // 显示其他公司的“外部群“
  const filteredGroups = useMemo(() => {
    let filtered = groups
    if (keyword.trim()) filtered = filtered.filter(g => keywordCompare(keyword.trim(), g.name))
    if (!includeExternal) filtered = filtered.filter(g => g.isCorpExternal)
    if (!includeCorpExternal) filtered = filtered.filter(g => !g.isCorpExternal)
    if (tags.length)
      filtered = filtered.filter(
        g => g.tags.find(tagId => tags.find(t => t.id === tagId)) !== undefined,
      )
    return filtered
  }, [groups, keyword, tags, includeExternal, includeCorpExternal])

  const [choosed, setChoosed] = useState(() => OrderedMap(initialChoosedGroups.map(g => [g.id, g])))
  const allChoosed = useMemo(
    () => !!filteredGroups.length && !filteredGroups.find(group => !choosed.has(group.id)),
    [filteredGroups, choosed],
  )
  const chooseAll = useCallback(() => {
    let newChoosed = choosed
    for (const group of filteredGroups)
      newChoosed = newChoosed.set(group.id, pick(group, 'id', 'ownerWxid', 'conversationId'))
    setChoosed(newChoosed)
  }, [filteredGroups, choosed])
  const cancelChooseAll = useCallback(() => {
    let newChoosed = choosed
    for (const group of filteredGroups) newChoosed = newChoosed.delete(group.id)
    setChoosed(newChoosed)
  }, [filteredGroups, choosed])
  const switchChoose = useCallback(
    (group: BatchApplyGroup) => {
      if (choosed.has(group.id)) setChoosed(choosed.delete(group.id))
      else setChoosed(choosed.set(group.id, pick(group, 'id', 'ownerWxid', 'conversationId')))
    },
    [choosed],
  )

  const goPrev = useCallback(() => {
    propsGoPrev({ groups: [...choosed.values()] })
  }, [propsGoPrev, choosed])

  const goNext = useCallback(() => propsChoosed([...choosed.values()]), [propsChoosed, choosed])

  return <div styleName="wrap">
    <div styleName="groups">
      <header>
        <Input
          placeholder="查找群"
          value={keyword}
          onInput={e => setKeyword((e.target as HTMLInputElement).value)}
        />

        <Tooltip title="按标签筛选">
          <BookOutlined styleName="tag-trigger" onClick={() => setChoosingTags(true)} />
        </Tooltip>
        <ChooseGroupTags
          visible={choosingTags}
          choosed={tags.map(t => t.id)}
          title="按标签筛选"
          onFinish={finishChooseTags}
        />
        {tags.length ? (
          <div styleName="tags">
            {tags.map(tag => <Tag
              key={tag.id}
              closable
              onClose={e => {
                e.preventDefault()
                removeTag(tag.id)
              }}
            >
              <span>{tag.name}</span>
            </Tag>)}
          </div>
        ) : null}

        <div styleName="type-filter">
          筛选：
          <Checkbox
            checked={includeCorpExternal}
            onChange={e => setIncludeCorpExternal(e.target.checked)}
          >
            本企业外部群
          </Checkbox>
          <Checkbox checked={includeExternal} onChange={e => setIncludeExternal(e.target.checked)}>
            非本企业外部群
          </Checkbox>
        </div>
      </header>
      <main>
        <header>
          <Checkbox checked={allChoosed} onClick={allChoosed ? cancelChooseAll : chooseAll}>
            全选{filteredGroups.length ? `（${filteredGroups.length}）` : ''}
          </Checkbox>
        </header>
        <div styleName="list">
          {filteredGroups.map(group => <GroupItem
            key={group.id}
            item={group}
            choosed={choosed.has(group.id)}
            switchChoose={switchChoose}
          />)}
        </div>
      </main>
    </div>

    <div styleName="choosed">
      <header>已选择 {choosed.size} 个群聊</header>
      <div styleName="list">
        {groups
          .filter(g => choosed.has(g.id))
          .map(group => <ChoosedGroupItem
            key={group.id}
            item={group}
            switchChoose={switchChoose}
          />)}
      </div>
      <footer>
        <Button onClick={goPrev}>上一步</Button>
        <Button type="primary" onClick={goNext} disabled={!choosed.size}>
          下一步
        </Button>
      </footer>
    </div>
  </div>
}

function GroupItem(props: {
  item: FormattedGroup
  choosed: boolean
  switchChoose: (item: FormattedGroup) => void
}) {
  const { item, choosed, switchChoose } = props

  return <Tooltip title={item.name} mouseEnterDelay={0.7} placement="right">
    <div styleName="group-item" onClick={() => switchChoose(item)}>
      <Checkbox checked={choosed}></Checkbox>
      <img src={defaultAvatar} />
      <div styleName="info">
        <div styleName="group-name-wrap">
          <span styleName="group-name">{item.name}</span>
          {item.isCorpExternal ? <Tag>本企业</Tag> : null}
          {item.creatorWxid === item.ownerWxid ? <Tag>群主</Tag> : null}
        </div>
        <div styleName="qywx-name">{item.qywxName}</div>
      </div>
    </div>
  </Tooltip>
}

function ChoosedGroupItem(props: {
  item: FormattedGroup
  switchChoose: (item: FormattedGroup) => void
}) {
  const { item, switchChoose } = props

  return <Tooltip title={item.name} mouseEnterDelay={0.7} placement="right">
    <div styleName="choosed-group-item">
      <img src={defaultAvatar} />
      <div styleName="info">
        <div styleName="group-name-wrap">
          <span styleName="group-name">{item.name}</span>
          {item.isCorpExternal ? <Tag>本企业</Tag> : null}
          {item.creatorWxid === item.ownerWxid ? <Tag>群主</Tag> : null}
        </div>
        <div styleName="qywx-name">{item.qywxName}</div>
      </div>
      <CloseCircleFilled onClick={() => switchChoose(item)} />
    </div>
  </Tooltip>
}
